package Modelo.Pessoa;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import Util.ExcecaoInstanciaNaoEncontrada;

public class PessoaDao {
	
	private Long codPessoa;
	private String nomePessoa;
	private String cpfPessoa;
	private String enderecoPessoa;
	private Calendar dataNascPessoa;
	private String emailPessoa;
	private String telefonePessoa;
	
	
	public PessoaDao() {
		super();
	}
	public Pessoa adicionarPessoa(Connection connection,Pessoa pessoa){
		/* Criar "queryString". 
		 * Interrogacoes serao os parametros passados ao objeto
		 * preparedStatement*/
		String queryString = "INSERT INTO Pessoa"
				+ " ( nomePessoa, cpfPessoa,"
				+ "enderecoPessoa, dataNascPessoa,emailPessoa,telefonePessoa)"
				+ " VALUES (?, ?, ?, ?, ?, ?)";
		//Objeto que ira enviar a querrystring ao banco de dados e 
		//criara as chaves primarias
		try (PreparedStatement preparedStatement = connection.prepareStatement(
				queryString, Statement.RETURN_GENERATED_KEYS)) {

			int i = 1;
			int insertedRows = 0;
			//Coloca os parametros na mesma ordem indicada na querrystring
			preparedStatement.setString(i++, pessoa.getNomePessoa());
			preparedStatement.setString(i++, pessoa.getCpfPessoa());
			preparedStatement.setString(i++, pessoa.getEnderecoPessoa());
			Timestamp dateNascPessoa = new Timestamp(pessoa.getDataNascPessoa().getTimeInMillis());
			preparedStatement.setTimestamp(i++, dateNascPessoa);
			preparedStatement.setString(i++, pessoa.getEmailPessoa());
			preparedStatement.setString(i++, pessoa.getTelefonePessoa());
			insertedRows = preparedStatement.executeUpdate(); //Executa o comando SQL

			if (insertedRows == 0) {
				throw new SQLException("Can not add row to table 'PessoaIntern'");
			}

			if (insertedRows > 1) {
				throw new SQLException("Duplicate row in table 'PessoaIntern'");
			}

			/* Pega a chave primaria. */
			ResultSet resultSet = preparedStatement.getGeneratedKeys();

			if (!resultSet.next()) {
				throw new SQLException(
						"JDBC driver did not return generated key.");
			}
			Long codPessoa = new Long(resultSet.getLong(1));

			return new Pessoa(codPessoa, pessoa.getNomePessoa(), pessoa.getCpfPessoa(),
					pessoa.getEnderecoPessoa(), pessoa.getDataNascPessoa(), pessoa.getEmailPessoa(), 
					pessoa.getTelefonePessoa());
			
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	public Pessoa buscarPessoa(Connection connection, Long codPessoa)
			throws ExcecaoInstanciaNaoEncontrada{
		
		
		String queryString = "SELECT nomePessoa, cpfPessoa,"
				+ "enderecoPessoa, dataNascPessoa,emailPessoa,telefonePessoa" +
				" FROM Pessoa WHERE codPessoa = ?";
		
		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)) {

			int i = 1;
			preparedStatement.setLong(i++, codPessoa);
			//Pega os Resultados da busca
			ResultSet resultSet = preparedStatement.executeQuery();

			if(!resultSet.next()){
				throw new ExcecaoInstanciaNaoEncontrada(codPessoa, "Pessoa");

			}
			
			i = 1;
			String nomePessoa = resultSet.getString(i++);
			String cpfPessoa = resultSet.getString(i++);
			String enderecoPessoa = resultSet.getString(i++);
			Calendar dataNascPessoa = new GregorianCalendar();
			dataNascPessoa.setTimeInMillis((resultSet.getTimestamp(i++)).getTime());
			String emailPessoa = resultSet.getString(i++);
			String telefonePessoa = resultSet.getString(i++);
			return new Pessoa(codPessoa, nomePessoa, cpfPessoa, enderecoPessoa, 
					dataNascPessoa, emailPessoa, telefonePessoa);


		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	public void removerPessoa(Connection connection, long codPessoa)
			throws ExcecaoInstanciaNaoEncontrada{
		String queryString = "DELETE FROM Pessoa WHERE codPessoa = ?";

		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)) {
			int i = 1;
			preparedStatement.setLong(i++, codPessoa);

			int removedRows = preparedStatement.executeUpdate();

			if(removedRows == 0){
				throw new ExcecaoInstanciaNaoEncontrada(codPessoa, "Pessoa");
			}

		} catch (SQLException e) {
			throw new RuntimeException(e);
		}

	}
	public void updatePessoa(Connection connection, Pessoa pessoa) 
			throws ExcecaoInstanciaNaoEncontrada {

		int updateRows = 0;

		String queryString = "UPDATE Pessoa "
				+ "SET nomePessoa = ?, cpfPessoa = ?, enderecoPessoa = ?" +
				", dataNascPessoa = ?, emailPessoa = ?, telefonePessoa = ? WHERE codPessoa = ?";

		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)){
			int i = 1;
			preparedStatement.setString(i++, pessoa.getNomePessoa());
			preparedStatement.setString(i++, pessoa.getCpfPessoa());
			preparedStatement.setString(i++, pessoa.getEnderecoPessoa());
			Timestamp dateNascPessoa = new Timestamp(pessoa.getDataNascPessoa().getTimeInMillis());
			preparedStatement.setTimestamp(i++, dateNascPessoa);
			preparedStatement.setString(i++, pessoa.getEmailPessoa());
			preparedStatement.setString(i++, pessoa.getTelefonePessoa());
			preparedStatement.setLong(i++, pessoa.getCodPessoa());
			updateRows = preparedStatement.executeUpdate();

			if(updateRows == 0){
				throw new ExcecaoInstanciaNaoEncontrada(pessoa.getCodPessoa(), "Pessoa");
			}

			else if(updateRows > 1){
				throw new SQLException("Linha duplicada para o identificador = '" + "' "
						+ "na tabela 'Pessoa'");
			}


		} catch (SQLException e) {
			throw new RuntimeException(e);
		}


	}
	
	public List<Pessoa> buscarTodosEventos(Connection connection, long codigoPessoa) {

		String queryString = "SELECT * FROM Pessoa" + " WHERE codPessoa = ?";

		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)) {
			int i = 1;
			preparedStatement.setLong(i++, codigoPessoa);

			ResultSet resultSet = preparedStatement.executeQuery();
			List<Pessoa> pessoas = new ArrayList<Pessoa>();

			while(resultSet.next()){
				i = 1;
				
				this.codPessoa = resultSet.getLong(i++);
				this.nomePessoa = resultSet.getString(i++);
				this.cpfPessoa = resultSet.getString(i++);
				this.enderecoPessoa = resultSet.getString(i++);
				this.dataNascPessoa.setTimeInMillis((resultSet.getTimestamp(i++)).getTime());
				this.emailPessoa = resultSet.getString(i++);
				this.telefonePessoa = resultSet.getString(i++);
				
				pessoas.add(new Pessoa(this.codPessoa, this.nomePessoa, this.cpfPessoa, this.enderecoPessoa, this.dataNascPessoa, this.emailPessoa, this.telefonePessoa));
			}
			return pessoas;

		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}
